package fr.louloutes.lolshooter.engine.objects;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

// need package visibility with LolSprite Objects
/**
 * Class ObjectGroup: handling groups of templated objects
 * 
 * @author Louloute
 * 
 * @param <E>
 */
public class ObjectGroup<E extends GameObject> extends HashSet<E>
{

	// ******* HashSet functions *********

	// null not supported
	/**
	 * Add an object to current group. Null object not supported
	 * 
	 * @param object
	 */
	@Override
	public boolean add( E object )
	{
		if ( object == null )
			return false;
		return super.add( object );
	}

	/**
	 * Add a collection of objects to current group
	 * 
	 * @param arg0
	 * @return
	 */
	@Override
	public boolean addAll( Collection<? extends E> arg0 )
	{
		boolean modified = false;
		for ( E e : arg0 )
		{
			// warning : must evaluate "add" function first ! Else, if
			// "ok==true", "add(e)" is not performed
			modified = add( e ) || modified;
		}
		return modified;
	}

	// ****** Brand new functions !! ********

	/**
	 * Return a list of all object in current group colliding with a particular
	 * object
	 * 
	 * @param gObject
	 * @return
	 */
	public List<GameObject> collide( GameObject gObject )
	{
		List<GameObject> result = new ArrayList<GameObject>();
		for ( GameObject inGroup : this )
		{
			if ( inGroup.getSprite().collide( gObject.getSprite() ) )
			{
				result.add( inGroup );
			}
		}
		return result;
	}

	/**
	 * Return a list of object colliding in a certain manner
	 * 
	 * TODO:doc this function
	 * 
	 * @param group
	 * @return
	 */
	public List<GameObject> collide( ObjectGroup<? extends GameObject> group )
	{
		// could use collide(LolSprite sprite) but can leads to lot of
		// "new List" operations (and a lot of empty list return...)
		List<GameObject> result = new ArrayList<GameObject>( this.size()
				+ group.size() );
		for ( GameObject o1 : this )
		{
			for ( GameObject o2 : this )
			{
				if ( o1.getSprite().collide( o2.getSprite() ) )
				{
					result.add( o1 );
					result.add( o2 );
				}
			}
		}
		return result;
	}
}
